package chariott.main;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import org.apache.commons.collections.MultiMap;

import chariott.partition.BinPackingOrder_FF;
import chariott.partition.BinPackingOrder_FF_DEC;
import chariott.partition.LeastUsedOrder;
import chariott.partition.RoundRobinOrder;
import chariott.testing.RunItem;
import chariott.testing.TestCase;

public class CostCalculator {

	public final static double M1VALUE = 0.06;
	public final static double BINSIZE = 500;
	public final static int numOfNodes = 10;
	public static double totalCost;
	public static double[] costs = new double[numOfNodes];

	public static void main(String[] args) {

		ArrayList<RunItem> itemsToRun = new ArrayList<RunItem>();
		Map<Integer, Double> myMap = new HashMap<Integer, Double>();
		Arrays.fill(costs, 0);

		Random rG = new Random();

		// create random test cases;
		for (int i = 0; i < 100; i++) {
			double randomWeight = rG.nextInt(100);
			itemsToRun.add(new TestCase("randomTest" + i, randomWeight));
		}

		RoundRobinOrder rr = new RoundRobinOrder(numOfNodes, itemsToRun);
		BinPackingOrder_FF_DEC bbfdec = new BinPackingOrder_FF_DEC(numOfNodes,
				itemsToRun, BINSIZE);
		BinPackingOrder_FF bbf = new BinPackingOrder_FF(numOfNodes, itemsToRun,
				BINSIZE);
		LeastUsedOrder lu = new LeastUsedOrder(numOfNodes, itemsToRun);

		MultiMap rrRuns = rr.generateRuns();
		MultiMap bbfdecRuns = bbfdec.generateRuns();
		MultiMap bbfRuns = bbf.generateRuns();
		MultiMap luRuns = lu.generateRuns();

		double rrValue = getTotalCost(rrRuns);
		double bbfdecValue = getTotalCost(bbfdecRuns);
		double bbfValue = getTotalCost(bbfRuns);
		double luValue = getTotalCost(luRuns);

		System.out.println("RR: " + rrValue);
		System.out.println("LU: " + luValue);
		System.out.println("BBFF: " + bbfValue);
		System.out.println("BBFDEC: " + bbfdecValue);

	}

	public static double getTotalCost(MultiMap map) {

		double allCosts = 0;

		for (int j = 0; j < map.size(); j++) {
			List myList = (List) map.get(j);
			double totalWeight = 0;
			for (Object o : myList) {
				TestCase myCase = (TestCase) o;
				totalWeight = totalWeight + myCase.getWeight();

				// System.out.println(myCase.getWeight());

			}

			// System.out.println("bucket #:" + j + " total weight" +
			// totalWeight);
			double hoursUsed = Math.ceil(totalWeight / 60);

			double cost = hoursUsed * M1VALUE;

			costs[j] = cost;

		}

		for (double d : costs)
			allCosts = allCosts + d;

		if (map.size() < numOfNodes) {
			double discount = (numOfNodes - map.size()) * M1VALUE;
			allCosts = allCosts - discount;
		}

		return allCosts;

	}

}
